from datetime import date, datetime, timedelta

from django.db.models import Q, F, Count, Sum
from django.shortcuts import render, redirect
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
from django.template import loader, RequestContext
from .models import BookInfo, HeroInfo


# Create your views here.

def index(request):
    # num='b'+1
    # return HttpResponse('hello')
    # return my_render(request,'index.html')
    # key必须与index.html里的模板变量名名字一致
    # return my_render(request, 'index.html', {'key': 'hello world'})
    return render(request, 'index.html', {'key': 'hello world'})


# 加载模板文件，对模板进行一些处理，返回给前端
def my_render(request, template_path, context_dict={}):
    # 1.加载模板文件, 模板对象
    temp = loader.get_template(template_path)
    # 2.定义模板上下文:给模板文件传递数据，模板渲染:产生标准的html内容
    res_html = temp.render(context_dict)
    # 3.返回给浏览器
    return HttpResponse(res_html)


def show_books(request):
    books = BookInfo.objects.all()
    # 下面的键必须是books，和模板变量名同。
    return render(request, 'booktest/show_books.html', {'books': books})


def detail(request, bid):
    # 1.根据bid查询图书信息
    book = BookInfo.objects.get(id=bid)
    # 2.根据book查询关联的英雄信息
    heros = book.heroinfo_set.all()
    # 3.使用模板
    return render(request, 'booktest/detail.html', {'book': book, 'heros': heros})


def create(request):
    '''新增一本图书'''
    # 1.创建BookInfo对象
    b = BookInfo()
    b.btitle = '跟龙哥学C语言'
    b.bpub_date = date(2019, 10, 1)
    # 2.保存进数据库
    b.save()
    # 3.返回应答,让浏览器再访问/books,重定向
    # return HttpResponse('ok')
    return HttpResponseRedirect('/books')


def delete(request, bid):
    '''删除点击的图书'''
    # 1.通过bid获取图书对象
    book = BookInfo.objects.get(id=bid)
    # 2.删除
    book.delete()
    # 3.重定向，让浏览器访问/index,我写的是访问/books
    return HttpResponseRedirect('/books')


def index2(request):
    # 练习F对象和Q对象
    print(BookInfo.objects.filter(bread__gt=F('bcomment') * 2))
    print(BookInfo.objects.filter(id__gt=2, bread__gt=19))
    print(BookInfo.objects.filter(Q(id__gt=2) & Q(bread__gt=19)))
    # 例：查询id大于3或者阅读量大于30的图书的信息。
    print(BookInfo.objects.filter(Q(id__gt=3) | Q(bread__gt=30)))
    # 例：查询id不等于3图书的信息。
    print(BookInfo.objects.filter(~Q(id=3)))
    return HttpResponse('hello python2')


# 使用聚合
def use_aggregate(request):
    print(BookInfo.objects.all().aggregate(Count('id')))
    print(BookInfo.objects.aggregate(Sum('bread')))
    # 例：统计所有图书的数目。
    print(BookInfo.objects.all().count())
    print(BookInfo.objects.count())
    # 例：统计id大于3的所有图书的数目。
    print(BookInfo.objects.filter(id__gt=3).count())
    return HttpResponse('ok')


# 关联查询
def realation_search(request):
    # 例：查询图书信息，要求图书关联的英雄的描述包含'八'。
    print(BookInfo.objects.filter(heroinfo__hcomment__contains='八'))
    # 例：查询图书信息，要求图书中的英雄的id大于3.
    print(BookInfo.objects.filter(heroinfo__id__gt=3))
    # 例：查询书名为“天龙八部”的所有英雄。
    print(HeroInfo.objects.filter(hbook__btitle='天龙八部'))
    return HttpResponse('ok')


def areas(request, Areas=None):
    '''获取广州市的上级地区和下级地区'''
    # 1.获取广州市的信息
    area = Areas.objects.get(atitle='深圳市')
    # 2.查询广州市的上级地区
    parent = area.aParent
    # 3.查询广州市的下级地址
    children = area.areas_set.all()
    # 使用模板
    return render(request, 'booktest/area.html', {'area': area, 'parent': parent, 'children': children})


def login(request):
    # 判断用户是否登录
    # if request.session.has_key('islogin'):
    #     # 用户已登录, 跳转到首页
    #     return redirect('/index')
    # if 'username' in request.COOKIES:
    #     # 获取记住的用户名
    #     username = request.COOKIES['username']
    # else:
    #     username = ''

    return render(request, 'booktest/login.html')


# '''{'username': username}'''

def login_check(request):
    '''登录校验视图'''
    # request.POST 保存的是post方式提交的参数 QueryDict
    # request.GET 保存是get方式提交的参数  类型也是 QueryDict
    # 获取用户输入验证码
    vcode1 = request.POST.get('vcode')
    # 获取session中保存的验证码
    vcode2 = request.session.get('verifycode')

    # 进行验证码校验
    if vcode1 != vcode2:
        # 验证码错误
        return redirect('/login')

    username = request.POST.get('username')
    password = request.POST.get('password')
    remember = request.POST.get('remember')
    if username == 'admin' and password == '123':
        reponse = redirect('/index')
        request.session['islogin'] = True  # 加了session，记住密码后就不会显示login页面了，直接显示index了（实现登录记忆）
        if remember == 'on':
            reponse.set_cookie('username', username, max_age=7 * 24 * 3600)
        return reponse
    else:
        return redirect('/login')


def test_ajax(request):
    '''显示ajax页面'''
    return render(request, 'booktest/test_ajax.html')


def ajax_handle(request):
    '''ajax请求处理'''
    # 返回的json数据 {'res':1}
    # num='b'+1
    return JsonResponse({'res': 1})


def login_ajax(request):
    return render(request, 'booktest/login_ajax.html')


def login_ajax_check(request):
    '''ajax登录校验'''
    # 1.获取用户名和密码
    username = request.POST.get('username')
    password = request.POST.get('password')

    # 2.进行校验,返回json数据
    if username == 'admin' and password == '123':
        # 用户名密码正确
        return JsonResponse({'res': 1})
        # return redirect('/index') ajax请求在后台，不要返回页面或者重定向，这样是不行的，一定要返回Json！
    else:
        # 用户名或密码错误
        return JsonResponse({'res': 0})


def set_cookie(request):
    '''设置cookie信息'''
    response = HttpResponse('设置cookie')
    # 设置一个cookie信息,名字为num, 值为2
    # response.set_cookie('num', 2)
    # 下面是设置cookie在两周之后过期
    print(datetime.now())
    # response.set_cookie('num', 2, max_age=14*24*3600)  #max_age和下面是等价的
    response.set_cookie('num', 1, expires=datetime.now() + timedelta(days=14))
    # 返回response
    return response


# /get_cookie
def get_cookie(request):
    '''获取cookie的信息'''
    # 取出cookie num的值
    num = request.COOKIES['num']
    print(num)
    return HttpResponse(num)


def set_session(request):
    '''设置session'''
    request.session['username'] = 'luke'
    request.session['age'] = 18
    # request.session.set_expiry(5)
    return HttpResponse('设置session')


# /get_session
def get_session(request):
    '''获取session'''
    username = request.session.get('username')
    age = request.session.get('age')
    return HttpResponse(username + ':' + str(age))


# 　/clear_session
def clear_session(request):
    '''清除session信息'''
    request.session.clear()
    # request.session.flush()
    return HttpResponse('清除成功')


# 使用模板变量
# /test_var
def test_var(request):
    '''模板变量'''
    my_dict = {'title': '字典键值'}
    my_list = [1, 2, 3]
    book = BookInfo.objects.get(id=1)
    # 定义模板上下文
    context = {'my_dict': my_dict, 'my_list': my_list, 'book': book}
    return render(request, 'booktest/test_var.html', context)


# 使用模板过滤器
def test_tags(request):
    '''模板标签'''
    # 1. 查找所有图书的信息
    books = BookInfo.objects.all()
    return render(request, 'booktest/test_tags.html', {'books': books})


# 使用自定义的模板过滤器
def test_filters(request):
    books = BookInfo.objects.all()
    return render(request, 'booktest/test_filters.html', {'books': books})


# 模板继承
def test_template_inhert(request):
    return render(request, 'booktest/child.html')


# HTML转义
def html_escape(request):
    '''html转义'''
    return render(request, 'booktest/html_escape.html', {'content': '<h1>hello</h1>'})


def change_pwd(request):
    if not request.session.has_key('islogin'):
        #     # 用户未登录，跳转到登录
        return redirect('/login')
    return render(request, 'booktest/change_pwd.html')


def change_pwd_action(request):
    '''模拟修改密码处理'''
    # 1.获取新密码
    pwd = request.POST.get('pwd')
    # 2.返回一个应答
    return HttpResponse('修改密码为:%s' % pwd)


# 验证码
from PIL import Image, ImageDraw, ImageFont


# from django.utils.six import BytesIO  #django 3以后丢弃了

# /verify_code
def verify_code(request):
    # 引入随机函数模块
    import random
    # 定义变量，用于画面的背景色、宽、高 RGB
    bgcolor = (random.randrange(20, 100), random.randrange(
        20, 100), 255)
    width = 100
    height = 25
    # 创建画面对象
    im = Image.new('RGB', (width, height), bgcolor)
    # 创建画笔对象
    draw = ImageDraw.Draw(im)
    # 调用画笔的point()函数绘制噪点
    for i in range(0, 100):
        xy = (random.randrange(0, width), random.randrange(0, height))
        fill = (random.randrange(0, 255), 255, random.randrange(0, 255))
        draw.point(xy, fill=fill)

    # 定义验证码的备选值,随机数
    str1 = 'ABCD123EFGHIJK456LMNOPQRS789TUVWXYZ0'
    # 随机选取4个值作为验证码
    rand_str = ''
    for i in range(0, 4):
        rand_str += str1[random.randrange(0, len(str1))]

    # 构造字体对象，ubuntu的字体路径为“/usr/share/fonts/truetype/freefont”
    font = ImageFont.truetype('corbel.ttf', 23)
    # 构造字体颜色
    fontcolor = (255, random.randrange(0, 255), random.randrange(0, 255))
    # 绘制4个字
    draw.text((5, 2), rand_str[0], font=font, fill=fontcolor)
    draw.text((25, 2), rand_str[1], font=font, fill=fontcolor)
    draw.text((50, 2), rand_str[2], font=font, fill=fontcolor)
    draw.text((75, 2), rand_str[3], font=font, fill=fontcolor)
    # 释放画笔
    del draw
    # 存入session，用于做进一步验证
    request.session['verifycode'] = rand_str
    # 内存文件操作
    import io
    buf = io.BytesIO()
    # 将图片保存在内存中，文件类型为png
    im.save(buf, 'png')
    # 将内存中的图片数据返回给客户端，MIME类型为图片png
    return HttpResponse(buf.getvalue(), 'image/png')


# 反向解析
def url_reverse(request):
    return render(request, 'booktest/url_reverse.html')

def show_args(request, a, b):
    return HttpResponse(str(a) + ':' + str(b))

def show_kwargs(request, c, d):
    return HttpResponse(str(c) + ":" + str(d))

from django.urls import reverse
# /test_redirect
def test_redirect(request):
    # 重定向到/index
    # return redirect('/index')
    # url = reverse('booktest:index')

    # 重定向到/show_args/1/2
    url = reverse('booktest:show_args', args=(1,2))

    # 重定向到/show_kwargs/3/4
    # url = reverse('booktest:show_kwargs', kwargs = {'c': 3, 'd': 4})
    return redirect(url)



# 静态文件
def static_test(request):
    return render(request,'booktest/static_test.html')
